package title1

import java.sql.{Connection, DriverManager, PreparedStatement}

/**
  *
  * Created by ThinkPad on 2017/12/31.
  * 工具类
  */
object IPUtils {
  // 定义一个方法，把ip地址转换为10进制
  /*  def ip2Long(ip: String): Long = {
      val fragments = ip.split("[.]")
      var ipNum = 0L
      for (i <- 0 until fragments.length) {
        ipNum = fragments(i).toLong | ipNum << 8L
      }
      ipNum
    }*/


  // 使用函数
  val ip2Long = (ip: String) => {
    val fragments = ip.split("[.]")
    var ipNum = 0L
    for (i <- 0 until fragments.length) {
      ipNum = fragments(i).toLong | ipNum << 8L
    }
    ipNum
  }


  // 二分搜索   根据给定的ip地址的十进制，获取到对应ip地址的归属地
  /*def search(ipNum: Long, ipRules: Array[(Long, Long, String)]): Int = {
    // 定义起点 终点
    var start = 0
    var end = ipRules.length - 1
    while (start <= end) {
      // 获取中间元素的位置
      var middle = (start + end) / 2
      // 如果ipNum正好在middle所在值的区间范围内，就可以直接返回了
      if (ipNum >= ipRules(middle)._1 && ipNum <= ipRules(middle)._2) {
        // 直接返回   返回给定ip地址在当前ip规则库中的索引位置
        return middle
      } else if (ipNum < ipRules(middle)._1) { // 在左区间
        // 把中间的值，当成新的终点
        end = middle - 1
      } else { // 在右区间
        // 把之前的终点，当成新的起点
        start = middle + 1
      }
    }
    //  如果没有搜索到匹配的值，就给一个默认值
    -1
  }*/

  // 二分搜索   根据给定的ip地址的十进制，获取到对应ip地址的归属地
  val search = (ipNum: Long, ipRules: Array[(Long, Long, String)]) => {
    // 定义起点 终点
    var start = 0
    var end = ipRules.length - 1
    // 定义一个标识
    var flag = false
    var result = -1
    while (start <= end && !flag) {
      // 获取中间元素的位置
      var middle = (start + end) / 2
      // 如果ipNum正好在middle所在值的区间范围内，就可以直接返回了
      if (ipNum >= ipRules(middle)._1 && ipNum <= ipRules(middle)._2) {
        // 如果满足条件，但是没有退出循环，整个程序进入死循环
        middle
        flag = true
        result = middle
      } else if (ipNum < ipRules(middle)._1) { // 在左区间
        // 把中间的值，当成新的终点
        end = middle - 1
      } else { // 在右区间
        // 把之前的终点，当成新的起点
        start = middle + 1
      }
    }
    result
  }
  val searchCity = (ipNum: Long, ipRules: Array[(Long, Long, String,String)]) => {
    // 定义起点 终点
    var start = 0
    var end = ipRules.length - 1
    // 定义一个标识
    var flag = false
    var result = -1
    while (start <= end && !flag) {
      // 获取中间元素的位置
      var middle = (start + end) / 2
      // 如果ipNum正好在middle所在值的区间范围内，就可以直接返回了
      if (ipNum >= ipRules(middle)._1 && ipNum <= ipRules(middle)._2) {
        // 如果满足条件，但是没有退出循环，整个程序进入死循环
        middle
        flag = true
        result = middle
      } else if (ipNum < ipRules(middle)._1) { // 在左区间
        // 把中间的值，当成新的终点
        end = middle - 1
      } else { // 在右区间
        // 把之前的终点，当成新的起点
        start = middle + 1
      }
    }
    result
  }


  // 定义了一个函数，参数就是迭代器
  val data2Mysql = (it: Iterator[(String, Int)],tableName:String) => {
    // 使用foreachPartition  迭代的变量是一个分区的数据，迭代器
    var conn: Connection = null
    var pstm: PreparedStatement = null
    // try  catch
    try {
      conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/scott?useUnicode=true&characterEncoding=UTF-8", "root", "123456")
      pstm = conn.prepareStatement("insert into "+tableName+" values (?,?)")
      // 因为拿到的每一个元素是一个迭代器，所以这里还需要循环迭代
      it.foreach({
        t =>
          pstm.setString(1, t._1)
          pstm.setInt(2, t._2)
          pstm.executeUpdate()
      })
    } catch {
      case e: Exception => println(e.printStackTrace())
    }
    finally {
      // 关闭连接
      if (pstm != null)
        pstm.close()
      if (conn != null) conn.close()
    }
  }
}
